package com.scalar.chiptrack.adaptor.jazz;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.CSVParserImpl;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: munugoti
 * Date: 6 Jan, 2010
 * Time: 12:19:33 PM
 */
public class JazzDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;

    private HashMap<String, FabSortLot> m_fabWipDataMap        = new HashMap<String, FabSortLot>();
    private HashMap<String, FabSortLot> m_zroExp2WipDataMap    = new HashMap<String, FabSortLot>();
    private HashMap<String, FabSortLot> m_vnExpWipDataMap      = new HashMap<String, FabSortLot>();
    private HashMap<String, ShippedLot> m_fabShipDataMap       = new HashMap<String, ShippedLot>();

    public JazzDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_JAZZ, WIP_TYPE_FAB );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_JAZZ );
            FabSortAdaptorDAO.setLogger( m_parserLogger );   // All the DAOs and Parser should be logging into same file
            ShippedLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading/creating JAZZ output directory from database, Exception: " + se);
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new JazzDataParser().execute();
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    //Execute Method
    public void execute() throws Exception
	{
       AdaptorUtils.printHeader( VENDOR_NAME_JAZZ, CONSTANT_PARSER );

       File doneDestDir = new File( m_dataOutputDir + "/done" );

       File wipDataoutDir = new File( m_dataOutputDir );

       File[] fileList = wipDataoutDir.listFiles();

       if ( ( fileList == null ) || ( fileList.length <= 3 ) )
       {
           log( "No file found in directory: " + wipDataoutDir );
           throw new ScalarException( "No file found in directory: " + wipDataoutDir + "----\n\n" );
       }

       DBTransaction dbTransaction 	= null;
       ArrayList<File> successFileList   	= new ArrayList<File>();
       boolean success             	= false;

       try
       {
           for ( int i = 0; i < fileList.length; i++ )
           {
               if ( fileList[i].isDirectory() )
               {
                   continue;
               }

               if ( fileList[i].getName() != null && fileList[i].getName().trim().startsWith(JazzAdaptor.FILE_NAME_WIP) )
               {
               	 	parseDailyWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
               }

               if ( fileList[i].getName() != null && fileList[i].getName().trim().startsWith(JazzAdaptor.FILE_NAME_SHIP) )
               {
               	 	parseShipmentReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
               }
           }
       }
       catch ( Exception e )
       {
           success = false;
           log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
           e.printStackTrace();
           throw e;
       }
       try
       {
           if ( m_zroExp2WipDataMap.isEmpty() == false )
           {
               log( " Updating Fab Lot Information" );
               FabSortAdaptorDAO.saveFabLot( null, m_zroExp2WipDataMap.values().iterator(), "ZRO_EXP2", VENDOR_NAME_JAZZ );
               success = true;
           }
           else
           {
               FabSortAdaptorDAO.closeFabSortLot( dbTransaction, "ZRO_EXP2", VENDOR_NAME_JAZZ );
           }
       }
       catch (ScalarException se)
       {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Fab Lot information into database: " + se);
          throw se;
       }
       try
       {
           if ( m_vnExpWipDataMap.isEmpty() == false )
           {
               log( " Updating Fab Lot Information" );
               FabSortAdaptorDAO.saveFabLot( null, m_vnExpWipDataMap.values().iterator(), "VN_EXP", VENDOR_NAME_JAZZ );
               success = true;
           }
           else
           {
               FabSortAdaptorDAO.closeFabSortLot( dbTransaction, "VN_EXP", VENDOR_NAME_JAZZ );
           }
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Fab Lot information into database: " + se);
          throw se;
      }
      // to save the FAB lot tables
      try
      {
           if ( m_fabWipDataMap.isEmpty() == false )
           {
               log( " Updating Fab Lot Information" );
               FabSortAdaptorDAO.saveFabLot( null, m_fabWipDataMap.values().iterator(), WIP_TYPE_FAB, VENDOR_NAME_JAZZ );
               success = true;
           }
           else
           {
               FabSortAdaptorDAO.closeFabSortLot( dbTransaction, WIP_TYPE_FAB, VENDOR_NAME_JAZZ );
           }
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Fab Lot information into database: " + se);
          throw se;
      }

      try
      {
          // Save shipping info -
          if ( m_fabShipDataMap.isEmpty() == false )
          {
              log( "Updating shipment Information" );
              ShippedLotDAO.saveShippedLot( null, m_fabShipDataMap.values().iterator() );
          }
      }
      catch ( Exception e )
      {
          success = false;
          log( "ERROR!! ERROR!! ERROR!! Could not update JAZZ Shipping information into database: " + e );
          e.printStackTrace();
          throw e;
      }

      // To Close the Drop Out Lots
      AdaptorDAO.closeDropOutLots( VENDOR_NAME_JAZZ );

      // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
      AdaptorDAO.sendAllNotifications( VENDOR_NAME_JAZZ, true, true, true );

      int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( JazzAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

      // Update Adaptor_Run_Info table
      try
      {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, JazzAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id );
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
      }
      catch ( ScalarException se )
      {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, JazzAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
       }
        // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
   }//end of execute method


   	private void parseDailyWipReport( String fileName ) throws Exception
   	{
   		if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;
        FabSortLot fabSortLot   = null;
        String lotNumber        = null;
        String partNumber       = null;

        try
        {
            File fabWipFile = new File( fileName );
            if ( fabWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Fab Wip Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Fab Wip Report..." );
            Parser parser = ParserFactory.getCSVParser( fabWipFile, '\t' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();

            while ( result.next() )
            {
                partNumber = result.getString("Sitime Part");
                lotNumber  = result.getString("Sitime Lotid");
                String processType = null;
                if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
                     if ( result.getString("Stage") != null && ( "ZRO_EXP2".equalsIgnoreCase(result.getString("Stage"))
                        || "RT_EXP".equalsIgnoreCase(result.getString("Stage")) || "OX_EXP".equalsIgnoreCase(result.getString("Stage")) ) )
                     {
                          processType = "ZRO_EXP2";

                          fabSortLot = ( FabSortLot ) m_zroExp2WipDataMap.get( partNumber + lotNumber );
                          if ( fabSortLot == null )
                          {
                             fabSortLot = new FabSortLot( VENDOR_NAME_JAZZ, processType );
                             m_zroExp2WipDataMap.put( partNumber + lotNumber , fabSortLot );
                          }
                     }
                     else if ( result.getString("Stage") != null &&  "VN_EXP".equalsIgnoreCase(result.getString("Stage")) )
                     {
                         processType = "VN_EXP";
                         fabSortLot = ( FabSortLot ) m_vnExpWipDataMap.get( partNumber + lotNumber );
                         if ( fabSortLot == null )
                         {
                             fabSortLot = new FabSortLot( VENDOR_NAME_JAZZ, processType );
                             m_vnExpWipDataMap.put( partNumber + lotNumber , fabSortLot );
                         }
                     }
                     else
                     {
                         processType = WIP_TYPE_FAB;

                         fabSortLot = ( FabSortLot ) m_fabWipDataMap.get( partNumber + lotNumber );
                         if ( fabSortLot == null )
                         {
                             fabSortLot = new FabSortLot( VENDOR_NAME_JAZZ, processType );
                             m_fabWipDataMap.put( partNumber + lotNumber , fabSortLot );
                         }
                     }

                     int quantity = 0;

                     if( fabSortLot.getQtyIn() != null )
                     {
                         try
                         {
                             quantity = Integer.parseInt( fabSortLot.getQtyIn() );
                         }
                         catch ( NumberFormatException ignore )
                         {
                         }
                         quantity += result.getInt("Qty");
                     }
                     else
                     {
                        quantity = result.getInt("Qty");
                     }

                     String waferIds = null;
                     if ( fabSortLot.getWaferID() != null )
                     {
                         waferIds =  fabSortLot.getWaferID();
						if( result.getString("Component IDs") != null && result.getString("Component IDs").trim().length() > 0 )
						{
							waferIds = waferIds + ";" + AdaptorUtils.getWaferIDsByFormat( result.getString("Component IDs").replaceAll(" ",",").replaceAll(";,",";") );
						}
                     }
                     else
                     {
					 	if( result.getString("Component IDs") != null && result.getString("Component IDs").trim().length() > 0 )
					 	{
	                       waferIds = AdaptorUtils.getWaferIDsByFormat(result.getString("Component IDs").replaceAll(" ",",").replaceAll(";,",";") );
					 	}
                     }

                     if ( quantity > 0 )
                     {
                         fabSortLot.setLotId( lotNumber );
                         fabSortLot.setCustProduct( partNumber );
                         fabSortLot.setFabLotNumber( lotNumber );
                         fabSortLot.setDateIn( StringUtils.formatDateToString(new Date() ) );
                         fabSortLot.setQtyIn( quantity +"");
                         fabSortLot.setStage( result.getString("Stage") );
                         fabSortLot.setFabLotNumber( lotNumber );
                         fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                         fabSortLot.setShip_fcst_date( result.getString("ECD") );
                         fabSortLot.setForcastedDateOut( result.getString("ECD") );
                         fabSortLot.setWaferID( waferIds );
                         fabSortLot.setProcess( result.getString("Process") );
                         if ( result.getString("Stage") != null && result.getString("Stage").toUpperCase().indexOf("HOLD") != -1 )
                         {
                             fabSortLot.setLotStatus( LOT_STATUS_HOLD );
                         }
                         else
                         {
                             fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                         }
                     }
                }

            }
        }
        catch ( Exception ex )
        {   System.out.println("ERROR!!!ERROR!!! While Parsing the Jazz Daily wip Sheet");
            ex.printStackTrace();
            throw ex;
        }

    }

    private void parseShipmentReport( String fileName ) throws Exception
    {

        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result     = null;
        ShippedLot shippedLot   = null;
        String lotNumber        = null;
        String partNumber       = null;
        String shipDate         = null;
        String nextLocation     = null;
        try
        {
            File detailShipFile = new File( fileName );
            if ( !detailShipFile.exists() )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Ship Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Ship Report..." );

            Parser parser = ParserFactory.getCSVParser( detailShipFile, '\t' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();

            LinkedList<String> headings = result.getHeadings();
            
            if( headings.get(0)  != null &&  (headings.get(0).indexOf("shipment_report.jsp") != -1
                    || headings.get(0).indexOf("Invalid Start Date") != -1 || headings.get(0).indexOf("center") !=-1 )  )
            {
                //System.out.println(" BEFORE RETURN " );
                return;
            }

            while ( result.next() )
            {
                partNumber = result.getString("Cust PN");
                lotNumber = result.getString("Lotid");

                shipDate   =   result.getString("Ship Date"); // giving as MM/dd/yyyy
                nextLocation = result.getString("Ship Location");

                if ( partNumber != null && partNumber.trim().length() >0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
                    shippedLot = (ShippedLot) m_fabShipDataMap.get(partNumber + lotNumber + shipDate + nextLocation + result.getString("PO Number") );
                    if (shippedLot == null)
                    {
                        shippedLot = new ShippedLot(VENDOR_NAME_JAZZ, LOCATION_TYPE_FAB );
                        m_fabShipDataMap.put(partNumber + lotNumber + shipDate+ nextLocation + result.getString("PO Number"), shippedLot);
                    }

                    int quantity = 0;
                    if ( shippedLot.getShipQty() != null )
                    {
                       try
                       {
                           quantity = Integer.parseInt( shippedLot.getShipQty() );
                       }
                       catch ( NumberFormatException ignore )
                       {
                           quantity = 0;
                       }
                       quantity += result.getInt("Qty");
                    }
                    else
                    {
                        quantity = result.getInt("Qty");
                    }

                    if ( quantity > 0 )
                    {
                        shippedLot.setLotNumber( lotNumber );
                        shippedLot.setPartNumber( partNumber );
                        shippedLot.setShipDate( shipDate );
                        shippedLot.setShipQty( quantity + "");
                        shippedLot.setMawb( result.getString("Waybill"));
                        shippedLot.setCustomerPO( result.getString("PO Number") );
                        shippedLot.setShippingDoc( result.getString("Ship #") );
                        shippedLot.setFlightNumber( result.getString("Carrier"));
                        shippedLot.setNextLocation( nextLocation );
                        shippedLot.setFabLotNumber( lotNumber );
                        shippedLot.setProcessType( LOCATION_TYPE_FAB );
                    }
                }
            }
        }
        catch(Exception ex)
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the JAZZ Ship Report");
            ex.printStackTrace();
            throw ex;

        }
    }

     private static void log( String message )
     {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}

